﻿using System;
using System.Collections.Generic;
using System.Text;

namespace SharpSoft.Geometries
{
    public struct Rect
    {
        public Rect(double x, double y, double width, double height)
        {
            if (width < 0 || height < 0)
            {
                throw new Exception("宽度与高度均不能为负数。");
            }
            this.X = x;
            this.Y = y;
            this._Width = width;
            this._Height = height;
        }
        public Rect(Point2D p1, Point2D p2)
        {
            this.X = Math.Min(p1.X, p2.X);
            this.Y = Math.Min(p1.Y, p2.Y);
            this._Width = Math.Abs(p1.X - p2.X);
            this._Height = Math.Abs(p1.Y - p2.Y);
        }

        public Rect(Point2D p, Vector2D v) : this(p, new Point2D(p.X + v.X, p.Y + v.Y))
        {

        }
        public Rect(Point2D p, Size2D s) : this(p.X, p.Y, s.Width, s.Height)
        {

        }
        /// <summary>
        /// 距离原点最近的顶点X坐标
        /// </summary>
        public double X { get; set; }
        /// <summary>
        /// 距离原点最近的顶点Y坐标
        /// </summary>
        public double Y { get; set; }

        private double _Width;
        /// <summary>
        /// 宽度
        /// </summary>
        public double Width
        {
            get { return _Width; }
            set
            {
                if (value < 0)
                {
                    throw new Exception("宽度不能为负数。");
                }
                _Width = value;
            }
        }

        private double _Height;
        /// <summary>
        /// 高度
        /// </summary>
        public double Height
        {
            get { return _Height; }
            set
            {
                if (value < 0)
                {
                    throw new Exception("高度不能为负数。");
                }
                _Height = value;
            }
        }

        /// <summary>
        /// 矩形是否包含指定点
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public bool Contains(Point2D p)
        {
            return p.X >= this.X && p.Y >= this.Y && p.X <= this.X + this.Width && p.Y <= this.Y + this.Height;
        }
        /// <summary>
         /// 获取矩形的中心点
         /// </summary>
         /// <returns></returns>
        public Point2D GetCenter()
        {

            return new Point2D(X + this.Width / 2, Y + this.Height / 2);
        }
        /// <summary>
        /// 对角线长度
        /// </summary>
        public double DiagonalLength
        {
            get
            {
                return Math.Sqrt(Width.Pow() + Height.Pow());
            }
        }
        /// <summary>
        /// 获取经过对角线与矩形宽在P1上的夹角
        /// </summary>
        public Radian DiagonalAngle
        {
            get
            {
                return (Radian)Math.Atan2(this.Height, this.Width);
            }
        }


        public override bool Equals(object obj)
        {
            if (obj is Rect r)
            {
                return r.X == this.X && r.Y == this.Y && r.Width == this.Width && r.Height == this.Height;
            }
            return false;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }
}
